在這篇文章中,我們將展示如何使用 Node.js 來連接外部 API(如 CoinGecko 的比特幣價格 API),並通過 WebSocket 將比特幣的實時價格推送到 React 前端進行渲染。這是一個典型的前後端交互實戰案例,通過 WebSocket 的特性,可以實現比傳統 HTTP 請求更加流暢的數據更新效果。
背景
使用傳統的 HTTP 請求模式,每次前端需要數據時,必須手動觸發請求,而 WebSocket 則可以讓服務器主動將數據推送給前端。這使得 WebSocket 特別適合於像金融數據監控這樣需要頻繁更新的場景。
項目需求
1.後端通過 CoinGecko API 獲取比特幣的實時價格。
2.後端使用 WebSocket 向前端定期推送比特幣價格。
3.前端通過 WebSocket 接收價格並即時渲染。
記得安裝npm install ws axios
const WebSocket = require("ws");
const axios = require("axios"); // 用來請求 CoinGecko API 的庫
const wss = new WebSocket.Server({ port: 8080 });
// 每隔 10 秒從 CoinGecko API 獲取比特幣價格
const fetchBitcoinPrice = async () => {
try {
const response = await axios.get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd");
return response.data.bitcoin.usd;
} catch (error) {
console.error("無法獲取比特幣價格", error);
return null;
}
};
// 當有客戶端連接時觸發
wss.on("connection", (ws) => {
console.log("客戶端已連接");
// 每隔 10 秒向所有連接的客戶端推送比特幣價格
const intervalId = setInterval(async () => {
const price = await fetchBitcoinPrice();
if (price) {
const message = JSON.stringify({
type: "bitcoinPriceUpdate",
price: price,
});
// 向所有已連接的客戶端推送價格更新
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
}
}, 10000); // 每 10 秒更新一次價格
ws.on("close", () => {
console.log("客戶端已斷開連接");
clearInterval(intervalId); // 清除定時器
});
});
console.log("WebSocket 服務器運行在 ws://localhost:8080");
import React, { useState, useEffect, useRef } from 'react';
function App() {
const [bitcoinPrice, setBitcoinPrice] = useState(null); // 儲存比特幣價格
const ws = useRef(null);
useEffect(() => {
// 使用 WebSocket 連接到比特幣價格數據 API
ws.current = new WebSocket('ws://localhost:8080'); // 替換為你後端 WebSocket 的地址
ws.current.onopen = () => {
console.log('WebSocket 連接成功');
};
// 當收到服務器的比特幣價格更新時
ws.current.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'bitcoinPriceUpdate') {
setBitcoinPrice(data.price); // 更新比特幣價格
}
};
ws.current.onclose = () => {
console.log('WebSocket 連接關閉');
};
ws.current.onerror = (error) => {
console.error('WebSocket 錯誤:', error);
};
return () => {
if (ws.current) {
ws.current.close();
}
};
}, []);
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>比特幣實時價格監控</h1>
<h2>當前比特幣價格:{bitcoinPrice ? `$${bitcoinPrice}` : '加載中...'}</h2>
</div>
);
}
export default App;
這樣,我們成功建立了一個簡單的比特幣價格監控應用。透過 Node.js 後端連接外部 API,並使用 WebSocket 即時推送數據給 React 前端,使得數據可以即時更新在頁面上。
但這種方式有明顯的缺點,例如為什麼設定更新間隔為 10 秒?這會導致數據更新變慢。原因在於頻繁的 API 請求會被阻擋,因為我們的資料是從外部 API 獲取的,這些 API 通常都有請求次數的限制。如果你使用爬蟲技術,或許可以更靈活,但也需要考慮爬蟲的合法性和技術挑戰。
這次練習的重點是讓你的服務端能夠接受外部數據,並將其通過 WebSocket 推送給前端,實現實時渲染。
原本想說架wss自簽,順便練習,結果架起來之後因為自簽的一些原因,瀏覽器或其他設備還是會有不安全,就沒說了,好了大概就這樣結束囉,感謝